package com.minelx.scriptbuilder.parse.parser;

import com.minelx.scriptbuilder.parse.matcher.*;
import com.minelx.scriptbuilder.script.IVariable;
import com.minelx.scriptbuilder.script.ScriptContext;
import com.minelx.sequence.CompositeMatcher;
import com.minelx.sequence.CompositeToResult;
import com.minelx.sequence.IStringScanner;
import com.minelx.sequence.ReturnMatcher;

public class CommonValueMatcher implements ReturnMatcher<IVariable, IStringScanner> {

	private final CompositeToResult<IVariable, IStringScanner> singleEffectiveParser;

	private final CompositeMatcher<Affection, Affection> multiAffectionsParser;

	public CommonValueMatcher(ScriptContext context) {
		singleEffectiveParser = new CompositeToResult<IVariable, IStringScanner>()
				.add(new StringMatcher())
				.add(new BoolMatcher())
				.add(new GlobalVariableMatcher(context))
				.add(new DigitMatcher())
		;
		multiAffectionsParser = new CompositeMatcher<Affection, Affection>()
				.add(new DotAttributeMatcher())
				.add(new ExecuteMatcher(context))
		;
	}

	@Override
	public boolean isMatch(IStringScanner scanner) {
		// FIXME 2021/3/18  wait for me!!!
		return true;
	}

	@Override
	public IVariable onMatched(IStringScanner scanner) {
		IVariable singleValue = singleEffectiveParser.orElse(scanner, IVariable.nil());

		Affection affection = new Affection(scanner, singleValue);
		return scanner.sequence(multiAffectionsParser, scanner1 -> affection)
				.findLast().orElse(affection).belongs();
	}

	public static class Affection {
		private final IStringScanner scanner;

		private IVariable effected;

		public Affection(IStringScanner scanner, IVariable effected) {
			this.scanner = scanner;
			this.effected = effected;
		}

		public IStringScanner getScanner() {
			return scanner;
		}

		public IVariable belongs() {
			return effected;
		}

		public void effectedBy(IVariable effected) {
			this.effected = effected;
		}
	}
}
